輕鬆學習 R 語言

郭耀仁

課堂所需連結

關於講師

關於我

工作經歷

  • Coupang Senior Data Analyst
  • SAS Analytical Consultant
  • CTBC Management Associate
  • McKinsey Research Intern

講師經驗

  • 台大資工系統訓練班(2016 - 現在)
  • 文化大學推廣部(2018)
  • 2017 資料科學年會講者
  • 國立台北商業大學(2017 秋)
  • 玉山商業銀行(2017 夏)

Could that data BE any tidier?

Google 圖片

Data Scientist: The Sexiest Job of the 21st Century.

Harvard Business Review OCT, 2012

The world’s most valuable resource is no longer oil, but data.

The Economist, May 6th 2017

資料科學的範疇

  • 資料技術
  • 視覺化
  • 機器學習
  • 高效能運算

資料科學的程式語言

The 2017 Top Programming Languages

在資料科學領域獨領風騷的 R 語言

For R (a domain specific language for data science) to rank in the 6th. Other data-oriented languages appear in the Top 50 rankings, including Matlab (#15), SQL (#23), Julia (#31) and SAS (#37).

關於 R 語言的二三事

  • 以 S 語言為基礎
  • 由奧克蘭大學的 Ross Ihaka 與 Robert Gentleman 所創造
  • 高階的直譯式語言
  • 使用者多為統計、計量經濟或生物醫學相關領域

有關 R 語言的特性

  • 免費
  • 社群
  • 跨平台
  • 彈性大

容易建立的開發環境

暸解 R 語言的核心概念

The way R works is pretty straightforward, you apply functions to objects. - Greg Martain

R 語言的應用場景

深入淺出的學習

三個階段

  • 動機
  • 基礎
  • 應用

動機

  • 開發環境
  • gapminder
  • dplyr
  • T 檢定
  • ggplot2

基礎

  • 快速入門
  • 變數型別
  • 流程控制
  • 自訂函數
  • 資料結構
  • 迴圈
  • 綜合練習

應用

  • 載入檔案
  • 網站爬蟲
  • 解決工作上的問題

開發環境

安裝 R

從 The Comprehensive R Archive Network(CRAN)下載安裝檔進行安裝

安裝 RStudio

RStudio 下載安裝檔進行安裝

第一次執行 RSudio

新增一個 R 程式

完整的四個區塊

  • 來源(Source):位於左上角,編寫程式的區塊
  • 命令列(Console):位於左下角,執行程式的區塊
  • 環境與歷史:位於右上角
  • 檔案、圖形、套件、查詢與預覽器:位於右下角

gapminder

The best stats you’ve ever seen

安裝與載入 gapminder

install.packages("gapminder")
library(gapminder)

看看 gapminder 資料

data("gapminder")
dim(gapminder)
summary(gapminder)
str(gapminder)

dplyr

安裝與載入 dplyr

install.packages("dplyr")
library(dplyr)

資料整理的文法

gapminder %>%
  filter(country == 'Taiwan' |
         country == 'South Africa') %>%
  group_by(country) %>%
  summarise(avg_lifeExp = mean(lifeExp))

T 檢定

函數 t.test()

df_ttest <- gapminder %>%
  filter(country == 'Taiwan' |
        country == 'South Africa')
t.test(data = df_ttest, lifeExp ~ country)

ggplot2

安裝與載入 ggplot2

install.packages("ggplot2")
library(ggplot2)

視覺化的文法

gg1 <- gapminder %>%
  filter(gdpPercap < 50000) %>% 
  ggplot(aes(x = gdpPercap, y = lifeExp)) +
  geom_point()
gg1

加上一些透明度

gg2 <- gapminder %>%
  filter(gdpPercap < 50000) %>% 
  ggplot(aes(x = gdpPercap, y = lifeExp, col = continent)) +
  geom_point(alpha = 0.3)
gg2

加入平滑趨勢線

gg3 <- gapminder %>%
  filter(gdpPercap < 50000) %>% 
  ggplot(aes(x = gdpPercap, y = lifeExp, col = continent)) +
  geom_point(alpha = 0.3) +
  geom_smooth()
gg3
## `geom_smooth()` using method = 'loess'

區分五個小圖

gg4 <- gapminder %>%
  filter(gdpPercap < 50000) %>% 
  ggplot(aes(x = gdpPercap, y = lifeExp, col = continent)) +
  geom_point(alpha = 0.3) +
  geom_smooth(method = "lm") +
  facet_wrap(~continent)
gg4

快速入門

賦值

lucky_number <- 24
lucky_number
## [1] 24

使用 c() 函數

意即 Combine

lucky_numbers <- c(24, 34)
lucky_numbers
## [1] 24 34

使用 ? or help() 查詢

?q
help(q)

使用 # 做註解

# 利用 c() 函數 --------------------------
lucky_numbers <- c(24, 34) # 將 24 與 34 多個值指派給 lucky_numbers 物件
lucky_numbers              # 印出 lucky_numbers
## [1] 24 34

R Console 可以使用的快捷鍵

  • 按向上的箭頭與向下的箭頭可以顯示出先前執行過的程式
  • 按 Ctrl 與 L 可以清除 R Console

宣告檔案的路徑

Windows 作業系統中路徑習慣使用正向斜線(Forward slash) 來表示不同資料夾階層,像是:

"C:\Users\user\MyDocuments\data.csv"

但是在 R 語言中要指派上面這個 data.csv 的絕對路徑時,必須要將  全部換成 / 才能被正確辨識

"C:/Users/user/MyDocuments/data.csv"

變數型別

三個基本變數型別

  • 數值 numeric
  • 文字 character
  • 邏輯值 logical

使用 class() 函數判斷

class(24)
## [1] "numeric"
class("Luke Skywalker")
## [1] "character"
class(TRUE) # class(FALSE)
## [1] "logical"

數值的運算

2 + 1
2 - 1
2 * 2
4 / 2
2**3
12 %% 8
17 %/% 8

計算 BMI

\[BMI = \frac{weight(kg)}{height(m)^2}\]

height <- 172
weight <- 65
bmi <- ___ / (___)**2
bmi

文字

使用雙引號與單引號

luke <- "Luke Skywalker"
luke <- 'Luke Skywalker'

雙引號與單引號何時有差別

Not only us get confused about quotes

邏輯值

  • TRUE
  • FALSE

邏輯判斷運算子

邏輯判斷運算子 作用
== 等於
> 大於
< 小於
>= 大於等於
<= 小於等於
!= 不等於

判斷型別

  • is.numeric()
  • is.character()
  • is.logical()

轉換型別

  • as.numeric()
  • as.character()
  • as.logical()

邏輯值應用情景

  • 資料篩選
  • 流程控制

資料篩選

篩選大於 2 的數字

num_vector <- c(1, 2, 3, 4, 5)
num_vector > 2
## [1] FALSE FALSE  TRUE  TRUE  TRUE
num_vector[num_vector > 2]
## [1] 3 4 5

流程控制

流程控制程式結構

if (條件一) {

    # 程式一

} else if (條件二) {

    # 程式二

} else {

    # 程式三

}

判斷 BMI 練習

BMI Diagnostics

自訂函數

為何要自訂函數

R 語言本質上是一個函數型語言

Everything that happens is a function call - John Chambers

自訂函數的外觀

function_name <- function(input_1, input_2, params_1, params_2, ...) {
  # 一些描述
  return() #把輸出回傳
}

計算平方數的函數

\(y = x^2\)

# 宣告函數
squared <- function(x) {
  return(x^2)
}

# 呼叫函數
squared(5)
## [1] 25

計算絕對值的函數

# 宣告函數
abs_fun <- function(x) {
  if (x < 0) {
    return(-x)
  } else {
    return(x)
  }
}

# 呼叫函數
abs_fun(-5)
## [1] 5
abs_fun(10)
## [1] 10

計算 BMI 的函數

get_bmi(172, 65)
## [1] 21.97134

資料結構

學習資料結構的三要點

  • 建立
  • 選擇
  • 迭代

向量

  • Vector 可以包含數字、文字或邏輯
  • 但是 Vector 只能有一種類型
  • 使用 c() 這個函數來建造 Vector,顧名思義是合併 (Combine)

資料框

  • 一個資料框中可以包含不同資料類別的變數
  • 使用 data.frame() 函數可以建立資料框(向量長度要相同)
name <- c("蒙其D魯夫", "羅羅亞索隆", "娜美", "賓什莫克香吉士")
is_female <- c(FALSE, FALSE, TRUE, FALSE)
age <- c(19, 21, 20, 21)
one_piece_df <- data.frame(name, is_female, age, stringsAsFactors = FALSE)
class(one_piece_df)
View(one_piece_df)

常用的資料框函數

  • dim()
  • summary()
  • str()
  • names()
  • head()
  • tail()

清單

  • 清單可以包含任意資料結構
  • 利用雙重中括號 [[]] 來選擇元素
char_vector <- c("I", "Love", "R")
my_vector <- 1:8
name <- c("蒙其D魯夫", "羅羅亞索隆", "娜美", "賓什莫克香吉士")
is_female <- c(FALSE, FALSE, TRUE, FALSE)
age <- c(19, 21, 20, 21)
one_piece_df <- data.frame(name, is_female, age, stringsAsFactors = FALSE)
my_list <- list(char_vector, my_vector, one_piece_df)

清單的重要性

  • 彈性的儲存空間
  • 函數的多重輸出

除了計算 BMI 也回傳標籤

get_bmi(172, 65)
## $bmi
## [1] 21.97134
## $label
## [1] "Normal"

迴圈

迴圈的好處

善用迴圈讓你能夠寫出簡短的程式碼

for 迴圈

# for 迴圈
for (i in month.name) {
  print(i)
}

while 迴圈

# while 迴圈
i <- 1
while (i < 13) {
  print(month.name[i])
  i <- i + 1
}

綜合練習

計算一個向量的長度

get_length(c(1, 2, 3))
## [1] 3

計算向量中的元素總和

get_sum(c(1, 2, 3))
## [1] 6

找出所有的正因數

get_divisors(87)
## [1] 1 3 29 87

判斷輸入是否為質數的函數

is_prime(87)
## [1] FALSE

讓使用者輸入兩個數字,函數會算出這兩個數字之間有幾個質數(包含輸入的兩個數字)

count_primes(3, 10)
## [1] 3

實作 Fibonacci 數列產生器的函數

Fibonacci 數列

fib_generator(0, 1, fib_len = 5)
## [1] 0 1 1 2 3

載入資料

資料

https://storage.googleapis.com/learn-r-the-easy-way.appspot.com/udemy_courses/data_import.zip

csv

  • 使用 read.csv() 函數
csv_file_path <- "Your csv file path"
df <- read.csv(csv_file_path)

txt

  • 使用 read.table() 函數
txt_file_path <- "Your text file path"
df <- read.table(txt_file_path, sep = "Text file separator", header = TRUE)

excel

  • 使用 readxl::read_excel() 函數
  • 僅能讀取本機端的 Excel 試算表
install.packages("readxl")
library(readxl)

xlsx_file_path <- "Your excel file path"
df <- read_excel(xlsx_file_path)

JSON

  • 使用 jsonlite::fromJSON() 函數
install.packages("jsonlite")
library(jsonlite)

json_file_path <- "Your json file path"
data_list <- fromJSON(json_file_path)

網站爬蟲

為什麼需要網站爬蟲?

  • 內部資料庫不一定有表格欄位
  • 外部資料庫要價昂貴
  • 資料就像衣櫃中的衣服,永遠少一件?
  • 能自動就不要手動

爬蟲程式的核心問題只有兩個

  • 獲取網站的回應(request)
  • 解析網站的回應(parser)

在爬蟲之前裝兩個 Chrome 外掛

CSS 選擇

XPath 選擇

rvest 套件

  • rvest to the rescue!
  • 重磅級的解決方案!
  • 一次搞定 request 與 parser!

安裝與載入 rvest

install.packages("rvest")
library(rvest)

read_html() 搞定 request

library(rvest)
## Loading required package: xml2
html_doc <- "http://www.imdb.com/title/tt3783958/" %>%
  read_html()

html_nodes() 搞定 parser

elem <- html_doc %>%
  html_nodes(css = "strong span")
  # html_nodes(xpath = "//strong/span")

html_text() 清理標籤

rating <- elem %>%
  html_text() %>%
  as.numeric()

解決工作上的問題

探討主題

管理學院學生的學習成效、教學意見之探討—以管理學為例

主題背景

某一天,管理學院院長想要瞭解企管系、財金系、文創系、運動系等四個科系,學生在大一管院必修的「管理學」課程之學習成效,以及學生對於「教師教學意見」調查表的結果,作為未來教學改進之參考。

載入試算表為資料框

Time for Live Coding!